En el contexto de la actual pandemia de COVID-19 muchos ideales de la planificación urbana se han puesto en duda. Uno de ellos, y quizás el más evidente, tiene que ver con los patrones de uso del suelo de los centros de las grandes ciudades.
Pesando en una posible revitalización urbana y en la incoporación de áreas verdes en zonas densas y consolidadas, nos preguntamos:
¿Es posible convertir los estacionamientos concesionados en áreas verdes?
¿Dónde se ubican? ¿Están espacialmente concentrados en el centro?
Consignas
En este trabajo elegiremos a la Ciudad Autónoma de Buenos Aires (CABA) como objeto de estudio.
Nuestro primer paso será cargar los datasets espaciales que incluyen los barrios y las manzanas de la ciudad.
barrios <- st_read ("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/barrios.geojson")
## Reading layer `barrios_badata' from data source
## `https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/barrios.geojson'
## using driver `GeoJSON'
## Simple feature collection with 48 features and 4 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## Geodetic CRS: WGS 84
manzanas <- st_read ("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/manzanas.geojson")
## Reading layer `manzanas' from data source
## `https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/manzanas.geojson'
## using driver `GeoJSON'
## Simple feature collection with 12520 features and 12 fields
## Geometry type: POLYGON
## Dimension: XYZ
## Bounding box: xmin: -58.53042 ymin: -34.70389 xmax: -58.33514 ymax: -34.52755
## z_range: zmin: 0 zmax: 49.894
## Geodetic CRS: WGS 84
La pandemia generó grandes transformaciones en las formas de habitar nuestras ciudades. En esta linea, a partir de los cambios en los patrones de movilidad, grandes espacios de la trama urbana dedicados al transporte, como los estacionamientos, quedaron en desuso, provocando así grandes vacíos urbanos, particularmente, en las zonas céntricas. De igual manera, la coyuntura puso en evidencia la falta de espacios verdes existente en la CABA.
Con el fin de construir una solución que permita reconvertir aquellas superficies obsoletas en espacios verdes y así mejorar la calidad de vida de las personas, en este trabajo analizaremos territorialmente la distribución de los estacionamientos urbanos.
A continuación abriremos los datasets de estacionamientos y de espacios verdes.
estacionamientos <- read.csv("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/estacionamientos.csv",
stringsAsFactors = TRUE,
encoding = "UTF-8")
espacioverde <- st_read("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/espacioverdepublico.geojson")
## Reading layer `espacio_verde_publico_WGS84' from data source
## `https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/espacioverdepublico.geojson'
## using driver `GeoJSON'
## Simple feature collection with 1731 features and 31 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -58.53175 ymin: -34.70557 xmax: -58.33983 ymax: -34.52657
## Geodetic CRS: WGS 84
Inspeccionamos nuestro dataset principal:
head(estacionamientos)
## long lat id nombre
## 1 -58.38934 -34.58391 1 FACULTAD DE DERECHO
## 2 -58.38222 -34.59424 2 9 DE JULIO e/ Santa Fe y Juncal
## 3 -58.38153 -34.60497 3 OBELISCO NORTE
## 4 -58.38170 -34.60256 4 9 DE JULIO Y LAVALLE
## 5 -58.38105 -34.61424 5 9 DE JULIO e/ Belgrano y México
## 6 -58.37683 -34.59881 6 CÓRDOBA
## tipo direccion_ calle_nombre
## 1 Facultad de Derecho
## 2 Estacionamiento Subterráneo 9 de Julio entre Santa Fe y Juncal
## 3 Estacionamiento Subterráneo 9 DE JULIO AV. y SARMIENTO
## 4 Estacionamiento Subterráneo 9 DE JULIO AV. y LAVALLE
## 5 Estacionamiento Subterráneo 9 de Julio entre Belgrano y México
## 6 Estacionamiento Subterráneo Córdoba entre Florida y Esmeralda
## calle_altura calle_cruce barrio comuna
## 1 NA
## 2 NA 9 de Julio entre Santa Fe y Juncal
## 3 NA 9 DE JULIO AV. y SARMIENTO San Nicolas Comuna 1
## 4 NA 9 DE JULIO AV. y LAVALLE San Nicolas Comuna 1
## 5 NA 9 de Julio entre Belgrano y México
## 6 NA Córdoba entre Florida y Esmeralda
## codigo_postal codigo_postal_argentino
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
nrow(estacionamientos)
## [1] 49
Hay 49 estacionamientos concesionados, de acuerdo a los datos del GCBA. Como existen missing values en las columnas de barrio y comuna, procederemos a eliminar dichas columnas y refernciar la información de manera espacial. Sólo nos quedaremos con las columnas que nos interesan para el análisis.
estacionamientos <- estacionamientos %>%
#seleccionamos las columnas
select(long, lat, id, nombre, tipo) %>%
#renombramos la columna de longitud, por comodidad
rename(lon=long) %>%
#levantamos el csv espacialmente, tomando los valores de longitud y latitud
st_as_sf(coords = c("lon", "lat"), crs = 4326)
Para saber cuántos estacionamientos concesionados hay por barrio, primero haremos una unión espacial de nuestros datasets.
#primero nos aseguramos que ambos datasets se encuentren en el mismo sistema de coordenadas.
barrios <- st_transform(barrios, crs=st_crs(estacionamientos))
estacionamientos <- st_join (estacionamientos, barrios)
head(estacionamientos)
## Simple feature collection with 6 features and 7 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -58.38934 ymin: -34.61424 xmax: -58.37683 ymax: -34.58391
## Geodetic CRS: WGS 84
## id nombre tipo barrio
## 1 1 FACULTAD DE DERECHO RECOLETA
## 2 2 9 DE JULIO e/ Santa Fe y Juncal Estacionamiento Subterráneo RETIRO
## 3 3 OBELISCO NORTE Estacionamiento Subterráneo SAN NICOLAS
## 4 4 9 DE JULIO Y LAVALLE Estacionamiento Subterráneo SAN NICOLAS
## 5 5 9 DE JULIO e/ Belgrano y México Estacionamiento Subterráneo MONSERRAT
## 6 6 CÓRDOBA Estacionamiento Subterráneo SAN NICOLAS
## comuna perimetro area geometry
## 1 2 21452.839 6317265 POINT (-58.38934 -34.58391)
## 2 1 18837.989 4512711 POINT (-58.38222 -34.59424)
## 3 1 6548.085 2289008 POINT (-58.38153 -34.60497)
## 4 1 6548.085 2289008 POINT (-58.3817 -34.60256)
## 5 1 6739.222 2198622 POINT (-58.38105 -34.61424)
## 6 1 6548.085 2289008 POINT (-58.37683 -34.59881)
Vemos que se le agregaron las columnas correspondientes a los datos de barrios (barrio, comuna, perímetro, área y geometry).
Paso siguiente, lo agruparemos por barrio y resumiremos por cantidad de estacionamiento. Luego, lo convertiremos en data.frame y eliminaremos la geometría.
estacionamientos_barrio <- estacionamientos %>%
group_by(barrio) %>%
summarise(cantidad=(n())) %>%
st_set_geometry(NULL) %>%
as.data.frame()
head(estacionamientos_barrio)
## barrio cantidad
## 1 BALVANERA 7
## 2 BELGRANO 1
## 3 CHACARITA 1
## 4 MONSERRAT 5
## 5 PALERMO 6
## 6 PUERTO MADERO 5
Logramos crear una tabla de datos donde sólo tenemos los nombres de los barrios y la cantidad de estacionamientos concesionados en cada uno de ellos.
Como paso siguiente, uniremos nuevamente nuestro dataset a los datos espaciales de barrios para recuperar la geometría.
estacionamientos_barrio <- left_join(barrios, estacionamientos_barrio, by="barrio")
Visualizamos.
ggplot()+
geom_bar(data=estacionamientos_barrio %>% filter(cantidad!=0), aes(y=reorder(barrio, -cantidad), weight=cantidad, fill=barrio), show.legend = FALSE)+
scale_fill_viridis_d()+
labs(x="Cantidad de estacionamientos concesionados",
y="Barrio",
title="¿Cuáles son los barrios con más estacionamientos en la Ciudad?",
caption="Fuente: GCBA")+
scale_x_continuous(breaks = seq(0, 12, 1))+
theme_minimal()
Mapeamos
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_sf(data=estacionamientos_barrio %>% filter(cantidad!=0), aes(fill=cantidad), alpha=.5, show.legend = FALSE)+
geom_sf_text(data=estacionamientos_barrio, aes(label=cantidad), size=4, fontface = "bold")+
scale_fill_viridis_c()+
labs(title="¿Cuántos estacionamientos concesionados hay por barrio?",
caption="Fuente: GCBA")+
theme_void()+
theme(plot.title = element_text( hjust = 0.5))
En este primer análisis observamos que el área central de la ciudad concentra casi la mitad de los estacionamientos concesionados de la CABA. A continuación, analizaremos esta cuestión con mayor profundidad.
Nuestro primer paso será geolocalizar las manzanas de la Ciudad. Como estas no cuentan con información del barrio en el que se ubican, procederemos a unir los datasets.
manzanas <- st_join(manzanas, barrios)
Luego, nos quedaremos con las manzanas pertenecientes a los barrios del microcentro porteño (Balvanera, Monserrat y San Nicolas).
microcentro <- filter(manzanas, barrio=="MONSERRAT" | barrio=="BALVANERA" | barrio=="SAN NICOLAS")
Utilizaremos este último dataset para filtrar los estacionamientos y espacios verdes de la CABA.
estacionamientos <- st_intersection(estacionamientos, microcentro)
espacioverde <- st_intersection(espacioverde, microcentro)
Y nos quedamos solo con aquellos estacionamientos que sean al nivel de la vereda.
estacionamientos<- filter(estacionamientos, tipo!="Estacionamiento Subterráneo")
Graficamos.
ggplot()+
geom_sf(data = microcentro, fill="grey96")+
geom_sf(data = espacioverde, fill="springgreen2")+
geom_sf(data = estacionamientos, aes(color="Estacionamientos"), size=2)+
scale_color_manual(values = c("Estacionamientos"="blue"))+
labs(title = "¿Dónde se ubican los estacionamientos del Microcentro porteño?",
color="",
subtitle = "",
caption = "Fuente: BA Data")+
theme_void()+
theme(plot.title = element_text(hjust = 0.5),
legend.position = "bottom",
legend.box.background = element_rect(color = "black"),
legend.box.margin = margin(3,6,3,6))
Ahora, analizaremos la ubicación de los estacionamientos en referencia a los espacios verdes y su cobertura. Particularmente, nos centraremos en identificar el rango de manzanas que se puden cubrir a pie en 5 minutos o menos desde un espacio verde.
puntosEspaciosVerdes <- map(1:nrow(espacioverde),function(x){st_sample(espacioverde[x,],size=4)})
puntosEspaciosVerdes <- do.call("c",puntosEspaciosVerdes)
puntosEspaciosVerdesSF <- st_as_sf(puntosEspaciosVerdes)
puntosEspaciosVerdesSF <- st_transform(puntosEspaciosVerdesSF,crs=4326)
isocronosEspaciosVerdes <- map(1:nrow(puntosEspaciosVerdesSF),function(x) {cat("Procesando: ",x,"\r")
isoline(puntosEspaciosVerdesSF[x,], transport_mode = "pedestrian",range_type = "time",range = 60*5)})
## Procesando: 1
Procesando: 2
Procesando: 3
Procesando: 4
Procesando: 5
Procesando: 6
Procesando: 7
Procesando: 8
Procesando: 9
Procesando: 10
Procesando: 11
Procesando: 12
Procesando: 13
Procesando: 14
Procesando: 15
Procesando: 16
Procesando: 17
Procesando: 18
Procesando: 19
Procesando: 20
Procesando: 21
Procesando: 22
Procesando: 23
Procesando: 24
Procesando: 25
Procesando: 26
Procesando: 27
Procesando: 28
Procesando: 29
Procesando: 30
Procesando: 31
Procesando: 32
Procesando: 33
Procesando: 34
Procesando: 35
Procesando: 36
Procesando: 37
Procesando: 38
Procesando: 39
Procesando: 40
Procesando: 41
Procesando: 42
Procesando: 43
Procesando: 44
Procesando: 45
Procesando: 46
Procesando: 47
Procesando: 48
Procesando: 49
Procesando: 50
Procesando: 51
Procesando: 52
Procesando: 53
Procesando: 54
Procesando: 55
Procesando: 56
Procesando: 57
Procesando: 58
Procesando: 59
Procesando: 60
Procesando: 61
Procesando: 62
Procesando: 63
Procesando: 64
Procesando: 65
Procesando: 66
Procesando: 67
Procesando: 68
Procesando: 69
Procesando: 70
Procesando: 71
Procesando: 72
Procesando: 73
Procesando: 74
Procesando: 75
Procesando: 76
Procesando: 77
Procesando: 78
Procesando: 79
Procesando: 80
Procesando: 81
Procesando: 82
Procesando: 83
Procesando: 84
Procesando: 85
Procesando: 86
Procesando: 87
Procesando: 88
Procesando: 89
Procesando: 90
Procesando: 91
Procesando: 92
Procesando: 93
Procesando: 94
Procesando: 95
Procesando: 96
Procesando: 97
Procesando: 98
Procesando: 99
Procesando: 100
Procesando: 101
Procesando: 102
Procesando: 103
Procesando: 104
Procesando: 105
Procesando: 106
Procesando: 107
Procesando: 108
Procesando: 109
Procesando: 110
Procesando: 111
Procesando: 112
Procesando: 113
Procesando: 114
Procesando: 115
Procesando: 116
Procesando: 117
Procesando: 118
Procesando: 119
Procesando: 120
Procesando: 121
Procesando: 122
Procesando: 123
Procesando: 124
Procesando: 125
Procesando: 126
Procesando: 127
Procesando: 128
Procesando: 129
Procesando: 130
Procesando: 131
Procesando: 132
Procesando: 133
Procesando: 134
Procesando: 135
Procesando: 136
Procesando: 137
Procesando: 138
Procesando: 139
Procesando: 140
Procesando: 141
Procesando: 142
Procesando: 143
Procesando: 144
Procesando: 145
Procesando: 146
Procesando: 147
Procesando: 148
Procesando: 149
Procesando: 150
Procesando: 151
Procesando: 152
Procesando: 153
Procesando: 154
Procesando: 155
Procesando: 156
Procesando: 157
Procesando: 158
Procesando: 159
Procesando: 160
Procesando: 161
Procesando: 162
Procesando: 163
Procesando: 164
Procesando: 165
Procesando: 166
Procesando: 167
Procesando: 168
Procesando: 169
Procesando: 170
Procesando: 171
Procesando: 172
Procesando: 173
Procesando: 174
Procesando: 175
Procesando: 176
Procesando: 177
Procesando: 178
Procesando: 179
Procesando: 180
Procesando: 181
Procesando: 182
Procesando: 183
Procesando: 184
Procesando: 185
Procesando: 186
Procesando: 187
Procesando: 188
Procesando: 189
Procesando: 190
Procesando: 191
Procesando: 192
Procesando: 193
Procesando: 194
Procesando: 195
Procesando: 196
Procesando: 197
Procesando: 198
Procesando: 199
Procesando: 200
Procesando: 201
Procesando: 202
Procesando: 203
Procesando: 204
Procesando: 205
Procesando: 206
Procesando: 207
Procesando: 208
Procesando: 209
Procesando: 210
Procesando: 211
Procesando: 212
Procesando: 213
Procesando: 214
Procesando: 215
Procesando: 216
Procesando: 217
Procesando: 218
Procesando: 219
Procesando: 220
Procesando: 221
Procesando: 222
Procesando: 223
Procesando: 224
Procesando: 225
Procesando: 226
Procesando: 227
Procesando: 228
Procesando: 229
Procesando: 230
Procesando: 231
Procesando: 232
Procesando: 233
Procesando: 234
Procesando: 235
Procesando: 236
Procesando: 237
Procesando: 238
Procesando: 239
Procesando: 240
Procesando: 241
Procesando: 242
Procesando: 243
Procesando: 244
Procesando: 245
Procesando: 246
Procesando: 247
Procesando: 248
Procesando: 249
Procesando: 250
Procesando: 251
Procesando: 252
Procesando: 253
Procesando: 254
Procesando: 255
Procesando: 256
Procesando: 257
Procesando: 258
Procesando: 259
Procesando: 260
Procesando: 261
Procesando: 262
Procesando: 263
Procesando: 264
Procesando: 265
Procesando: 266
Procesando: 267
Procesando: 268
Procesando: 269
Procesando: 270
Procesando: 271
Procesando: 272
Procesando: 273
Procesando: 274
Procesando: 275
Procesando: 276
Procesando: 277
Procesando: 278
Procesando: 279
Procesando: 280
Procesando: 281
Procesando: 282
Procesando: 283
Procesando: 284
Procesando: 285
Procesando: 286
Procesando: 287
Procesando: 288
Procesando: 289
Procesando: 290
Procesando: 291
Procesando: 292
Procesando: 293
Procesando: 294
Procesando: 295
Procesando: 296
Procesando: 297
Procesando: 298
Procesando: 299
Procesando: 300
Procesando: 301
Procesando: 302
Procesando: 303
Procesando: 304
Procesando: 305
Procesando: 306
Procesando: 307
Procesando: 308
Procesando: 309
Procesando: 310
Procesando: 311
Procesando: 312
Procesando: 313
Procesando: 314
Procesando: 315
Procesando: 316
Procesando: 317
Procesando: 318
Procesando: 319
Procesando: 320
Procesando: 321
Procesando: 322
Procesando: 323
Procesando: 324
Procesando: 325
Procesando: 326
Procesando: 327
Procesando: 328
Procesando: 329
Procesando: 330
Procesando: 331
Procesando: 332
Procesando: 333
Procesando: 334
Procesando: 335
Procesando: 336
isocronosEspaciosVerdesJuntas <- do.call(rbind,isocronosEspaciosVerdes)
isocronosEspaciosVerdesJuntasUnion <- st_union(isocronosEspaciosVerdesJuntas)
isocronosEspaciosVerdesJuntasUnion <- st_as_sf(isocronosEspaciosVerdesJuntasUnion) %>%
mutate(cobertura=TRUE)
Graficamos.
ggplot()+
geom_sf(data = microcentro, fill="grey96")+
geom_sf(data = espacioverde, fill="springgreen2")+
geom_sf(data = estacionamientos, aes(color="Estacionamientos"), size=2)+
geom_sf(data = isocronosEspaciosVerdesJuntasUnion, aes(fill="Cobertura de espacios verdes"), alpha=0.25, color="black")+
scale_color_manual(values = c("Estacionamientos"="blue"))+
scale_fill_manual(values = c("Cobertura de espacios verdes"="lightgreen"))+
labs(title = "¿Cuál es la cobertura de espacios verdes del Microcentro?",
color="",
fill="",
subtitle = "Manzanas a 5 min. o menos de un espacio verde",
caption = "Fuente: BA Data")+
theme_void()+
theme(plot.title = element_text(hjust = 0.5, face="bold"),
plot.subtitle = element_text(hjust = 0.5),
legend.position = "bottom",
legend.box.background = element_rect(color = "black"),
legend.box.margin = margin(3,6,3,6))
Ahora comparemos los estacionamientos, pero utilizando las estaciones de Ecobicis y su cobertura como referencia. Repitamos el proceso.
bbox_microcentro <- as.numeric(st_bbox(microcentro))
mapamicrocentro <- get_stamenmap(bbox = bbox_microcentro,
maptype = "toner-lite",
zoom=15)
ecobicis <- st_read("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis.geojson")
## Reading layer `estaciones_de_bicicletas_WGS84' from data source
## `https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis.geojson'
## using driver `GeoJSON'
## Simple feature collection with 229 features and 7 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -58.51142 ymin: -34.66051 xmax: -58.35574 ymax: -34.5445
## Geodetic CRS: WGS 84
ecobicis <- st_intersection(ecobicis, microcentro)
isocronosbicis <- map(1:nrow(ecobicis),function(x) {cat("Procesando: ",x,"\r")
isoline(ecobicis[x,], transport_mode = "pedestrian",range_type = "time",range = 60*5)})
## Procesando: 1
Procesando: 2
Procesando: 3
Procesando: 4
Procesando: 5
Procesando: 6
Procesando: 7
Procesando: 8
Procesando: 9
Procesando: 10
Procesando: 11
Procesando: 12
Procesando: 13
Procesando: 14
isocronosbicisjuntas <- do.call(rbind,isocronosbicis)
isocronosbicisjuntasunion <- st_union(isocronosbicisjuntas)
isocronosbicisjuntasunion <- st_as_sf(isocronosbicisjuntasunion) %>%
mutate(cobertura=TRUE)
Grafiquemos.
ggmap(mapamicrocentro)+
geom_sf(data = microcentro, fill="grey96", inherit.aes = FALSE)+
geom_sf(data = espacioverde, fill="mediumseagreen", inherit.aes = FALSE)+
geom_sf(data = ecobicis, aes(color="Ecobicis"), size=2, inherit.aes = FALSE)+
geom_sf(data = estacionamientos, aes(color="Estacionamientos"), size=2, inherit.aes = FALSE)+
geom_sf(data = isocronosbicisjuntasunion, aes(fill="A 5 min o menos a pie de una estación de Ecobicis"), color="coral1", alpha=0.20, color="black", inherit.aes = FALSE)+
scale_fill_manual(values = c("A 5 min o menos a pie de una estación de Ecobicis"="chocolate2"))+
scale_color_manual(values = c("Estacionamientos"="blue", "Ecobicis"="orangered"))+
labs(title = "¿Y si transformamos los estacionamientos del centro porteño en espacios verdes?",
subtitle = "",
fill="",
color="",
caption = "Fuente: BA Data")+
theme_void()+
theme(plot.title = element_text(size= 12, hjust = 0.5, face="bold"),
plot.caption=element_text(face = "italic", size=8),
legend.position = "bottom",
legend.box.background = element_rect(color = "black"),
legend.box.margin = margin(3,6,3,6))
Consignas
Primero, creamos la caja de coordenadas de la CABA.
bbox_CABA <- getbb("Ciudad Autónoma de Buenos Aires, Argentina")
Nos fijamos que las coordenadas extraídas sean las precisas.
mapa_CABA <- get_stamenmap(bbox = bbox_CABA,
maptype = "terrain",
zoom=12)
ggmap(mapa_CABA)+
theme_void()
Segundo, creamos un dataset con las calles de CABA. Para ello:
1º. Consultamos la info disponible.
CABA_calles <- opq(bbox_CABA) %>%
add_osm_feature(key="highway")
2º. Descargamos la info.
CABA_calles <- osmdata_sf(CABA_calles)
3º. Seleccionamos solo las líneas y las asignamos a nuestra lista para que se transfome en un dataset.
CABA_calles <- CABA_calles$osm_lines
Graficamos para ver el resultado
ggmap(mapa_CABA)+
geom_sf(data = CABA_calles, color="deepskyblue4", alpha=0.5, inherit.aes = FALSE)+
labs(title="Calles de la Ciudad Autónoma de Buenos Aires",
caption="Fuente: Open Street Map")+
theme_void()+
theme(plot.title = element_text(hjust = 0.5))
Como vemos, no solo nos descarga las calles de la CABA sino de todo el sistema de coordenadas. Para solucionar ese problema, haremos lo siguiente:
1º Descargamos el límite de la CABA.
bbox_CABA_limite <- getbb("Ciudad Autónoma de Buenos Aires, Argentina", format_out = "sf_polygon")
bbox_CABA_limite <- bbox_CABA_limite$multipolygon
ggmap(mapa_CABA)+
geom_sf(data=bbox_CABA_limite, fill=NA, size=1, color="firebrick3", inherit.aes = FALSE)+
labs(title="Ciudad Autónoma de Buenos Aires",
caption="Fuente: Open Street Map")+
theme_void()
2º Intersectamos nuestro dataset de calles con el del límite.
CABA_calles <- st_intersection(CABA_calles, bbox_CABA_limite)
Graficamos.
ggmap(mapa_CABA)+
geom_sf(data=bbox_CABA_limite, fill=NA, size=1, color="firebrick3", inherit.aes = FALSE)+
geom_sf(data = CABA_calles, color="deepskyblue4", alpha=0.5, inherit.aes = FALSE)+
labs(title="Calles de la Ciudad Autónoma de Buenos Aires",
caption="Fuente: Open Street Map")+
theme_void()+
theme(plot.title = element_text(hjust = 0.5))
Por último, coloreamos nuestras calles de acuerdo a la velocidad máxima permitida.
CABA_calles <- mutate(CABA_calles, maxspeed= fct_relevel(maxspeed, "5", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100", "130"))
ggmap(mapa_CABA)+
geom_sf(data = filter(CABA_calles, !(is.na(maxspeed))), aes(color=maxspeed), fill=NA, inherit.aes = FALSE)+
scale_color_viridis_d()+
labs(title="Calles de la Ciudad Autónoma de Buenos Aires",
color="Velocidad máxima (KM/H)",
caption="Fuente: Open Street Map")+
theme_void()
En línea con nuestro trabajo anterior, procederemos a descargar los estacionamientos de la CABA.
parking_CABA_OSM <- opq (bbox_CABA) %>%
add_osm_feature(key="building", value="parking")
parking_CABA_OSM <- osmdata_sf(parking_CABA_OSM)
parking_CABA_OSM <- parking_CABA_OSM$osm_points
Graficamos para ver su ubicación.
ggmap(mapa_CABA)+
geom_sf(data = parking_CABA_OSM, aes(color="Estacionamientos"), inherit.aes = FALSE)+
scale_color_manual(values = c("Estacionamientos"="red2"))+
labs(title="Ciudad Autónoma de Buenos Aires",
color="Referencias",
caption="Fuente: Open Street Map")+
theme_void()
Al igual que hicimos con las calles, nos quedaremos unicamente con los estacionamientos que se encuentren dentro de la CABA.
parking_CABA_OSM <- st_intersection(parking_CABA_OSM, bbox_CABA_limite)
Nos quedamos solo con los valores únicos.
parking_CABA_OSM <- unique(parking_CABA_OSM)
Graficamos para ver los resultados.
ggmap(mapa_CABA)+
geom_sf(data = parking_CABA_OSM, aes(color="Estacionamientos"), inherit.aes = FALSE)+
scale_color_manual(values = c("Estacionamientos"="red2"))+
labs(title="Ciudad Autónoma de Buenos Aires",
color="Referencias",
caption="Fuente: Open Street Map")+
theme_void()
Al ver el mapa anterior, podemos observar que hay algo que no anda bien. Nuestro dataset de estacionamientos contiene 87 registros, aunque sólo aparecen geolocalizados unos pocos puntos. Ello puede deberse a que la posición de los mismos está mal cargada.
No obstante, en Open Street Maps es posible encontrar que los estacionamientos se encuentran divididos en múltiples categorías. Probemos con otra categoría mucho más amplia que la original y repitamos el proceso:
parking_CABA_OSM_B <- opq (bbox_CABA) %>%
add_osm_feature(key="amenity", value="parking")
parking_CABA_OSM_B <- osmdata_sf(parking_CABA_OSM_B)
parking_CABA_OSM_B <- parking_CABA_OSM_B$osm_points
parking_CABA_OSM_B <- st_intersection(parking_CABA_OSM_B, bbox_CABA_limite)
parking_CABA_OSM_B <- unique(parking_CABA_OSM_B)
Grafiquemos
ggmap(mapa_CABA)+
geom_sf(data = parking_CABA_OSM_B, aes(color="Estacionamientos"), inherit.aes = FALSE)+
scale_color_manual(values = c("Estacionamientos"="red2"))+
labs(title="Ciudad Autónoma de Buenos Aires",
color="Referencias",
caption="Fuente: Open Street Map")+
theme_void()
Como podemos ver en el mapa anterior, la mayor concentración de estacionamientos se da en el corredor que se extiende desde el centro de la CABA hacia el norte. No obstante, es importante reconocer que los estacionamientos se muestran distribudios a lo largo y ancho de la ciudad.
Ahora, crucemos nuestro dataset de estacionamientos con el de barrios para conocer su distribución por cada uno de estos.
parking_CABA_OSM_B <- st_transform(parking_CABA_OSM_B, crs = st_crs(barrios))
parking_CABA_OSM_B <- st_join(parking_CABA_OSM_B, barrios)
Agrupemos los casos por barrio.
parking_CABA_OSM_barrio <- parking_CABA_OSM_B %>%
group_by(barrio) %>%
summarise(Q_estacionamientos=(n())) %>%
st_set_geometry(NULL) %>%
as.data.frame() %>%
filter(!is.na(barrio))
Grafiquemos.
ggplot()+
geom_bar(data=parking_CABA_OSM_barrio %>% filter(Q_estacionamientos !=0), aes(y=reorder(barrio, -Q_estacionamientos), weight=Q_estacionamientos, fill=barrio), show.legend = FALSE)+
scale_fill_viridis_d()+
labs(x="Cantidad de estacionamientos",
y="Barrio",
title="¿Cuántos estacionamientos por barrio existen en la CABA \n\ según OSM?",
caption="Fuente: OSM")+
scale_x_continuous(breaks = seq(0, 500, 50))+
theme_minimal()
parking_CABA <- left_join(barrios, parking_CABA_OSM_barrio, by="barrio")
Visualizamos.
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_sf(data=parking_CABA %>% filter(Q_estacionamientos!=0), aes(fill=Q_estacionamientos), alpha=.5, show.legend = FALSE)+
geom_sf_text(data=parking_CABA, aes(label=Q_estacionamientos), size=4, fontface = "bold")+
scale_fill_viridis_c()+
labs(title="¿Cuántos estacionamientos concesionados hay por barrio según OSM?",
caption="Fuente: OSM")+
theme_void()+
theme(plot.title = element_text( hjust = 0.5))
Comparemoslo con nuestro GEOJSON original.
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_sf(data=estacionamientos_barrio %>% filter(cantidad!=0), aes(fill=cantidad), alpha=.5, show.legend = FALSE)+
geom_sf_text(data=estacionamientos_barrio, aes(label=cantidad), size=4, fontface = "bold")+
scale_fill_viridis_c()+
labs(title="¿Cuántos estacionamientos concesionados hay por barrio?",
caption="Fuente: GCBA")+
theme_void()+
theme(plot.title = element_text( hjust = 0.5))
La primer observación que obtenemos es que nuestro N aumento considerablemente. Luego, si bien la mayor concentración de estacionamientos se da en el eje Centro - Norte de la CABA (siendo Palermo el principal barrio ahora), existe una oferta cosiderable en barrios perífericos como Lugano, Caballito, La Boca, Flores y Villa Soldati.
Estas diferencias pueden deverse a varios factores. Sin embargo, es importante reconocer que, mientras nuestro GEOJSON original nos daba sólo la ubicación de los estacionamientos concesionados, el nuevo dataset con datos de OSM ofrece información de todos los tipos de estacionamientos existentes en la CABA.
Veamos las diferencias con mayor precisión:
estacionamientos_barrio[is.na(estacionamientos_barrio)] <- 0
parking_OSM_GCBA <- left_join(parking_CABA_OSM_barrio, estacionamientos_barrio, by="barrio") %>%
rename("cantidad_GCBA"="cantidad") %>%
group_by(barrio, Q_estacionamientos, cantidad_GCBA) %>%
summarise(diferencia= Q_estacionamientos-cantidad_GCBA)
head(parking_OSM_GCBA, y=reorder(barrio, -diferencia))
## # A tibble: 6 x 4
## # Groups: barrio, Q_estacionamientos [6]
## barrio Q_estacionamientos cantidad_GCBA diferencia
## <chr> <int> <dbl> <dbl>
## 1 AGRONOMIA 39 0 39
## 2 ALMAGRO 71 0 71
## 3 BALVANERA 168 7 161
## 4 BARRACAS 68 0 68
## 5 BELGRANO 319 1 318
## 6 BOCA 108 0 108
ggplot()+
geom_bar(data=parking_OSM_GCBA, aes(y=reorder(barrio, -Q_estacionamientos), weight=Q_estacionamientos, fill=barrio), show.legend = FALSE)+
geom_bar(data=parking_OSM_GCBA, aes(y=reorder(barrio, -Q_estacionamientos), weight=cantidad_GCBA, fill=barrio), fill="red", show.legend = FALSE)+
scale_fill_viridis_d()+
labs(x="Diferencia (cantidad de estacionamientos)",
y="Barrio",
title="¿Cuánto difieren los datos de OSM con respecto a los del GCBA?",
caption="Fuente: GCBA + OSM",
fill="Estacionamientos GCBA")+
scale_x_continuous(breaks = seq(0, 500, 50))+
theme_minimal()
Mapeamos las diferencias para el área del Microcentro porteño.
parking_microcentro <- parking_CABA_OSM_B %>%
filter(barrio=="MONSERRAT" | barrio=="BALVANERA" | barrio=="SAN NICOLAS") %>%
filter(parking!="underground" | layer!="-1")
ggplot()+
geom_sf(data = microcentro, fill="grey96")+
geom_sf(data = espacioverde, fill="springgreen2")+
geom_sf(data = estacionamientos, aes(color="Estacionamientos GCBA"), size=2, alpha=0.5)+
geom_sf(data=parking_microcentro, aes(color="Estacionamientos OSM"), size=2, alpha=0.5)+
scale_color_manual(values = c("Estacionamientos GCBA"="blue", "Estacionamientos OSM"="red"))+
labs(title = "¿Dónde se ubican los estacionamientos del Microcentro porteño \n según las distintas fuentes?",
color="",
subtitle = "",
caption = "Fuente: BA Data")+
theme_void()+
theme(plot.title = element_text(hjust = 0.5),
legend.position = "bottom",
legend.box.background = element_rect(color = "black"),
legend.box.margin = margin(3,6,3,6))
Como podemos observar, las diferencias entre los datos provistos por el GEOJSON y los datos recolectados por OSM divergen considerablemente. Esto es así de tal manera que ambos sets de datos sólo coinciden en la ubicación de dos estacionamientos.
Consignas
En esta parte del trabajo, retomaremos el análisis de las Ecobicis y los viajes realizados en el área central de la Ciudad de Buenos Aires. Ello nos permitirá estudiar con mayor precisión el nivel de movilidad en el área durante la pandemia y hacer suposiciones sobre como podría impactar la promoción de nuevos espacios verdes en la zona.
Con este fin, utilizaremos el datset de viajes en bicicleta del año 2020:
ACLARACIÓN: Debido al tamaño del dataset original y su imposibilidad de subirlo a github, optamos por utilizar una versión más pequeña que solo contiene los viajes iniciados en estaciones del Microcentro porteño.
bicis_2020 <- read_csv("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro.csv")
str(bicis_2020)
## spec_tbl_df [109,490 x 24] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ X1 : num [1:109490] 14674 14675 14676 14677 14678 ...
## $ duracion_recorrido : num [1:109490] 1570 1648 1283 1700 1772 ...
## $ id_estacion_origen : num [1:109490] 51 51 51 51 51 51 51 51 51 51 ...
## $ fecha_origen_recorrido: POSIXct[1:109490], format: "2020-12-11 20:40:27" "2020-11-21 18:05:19" ...
## $ nombre_estacion_origen: chr [1:109490] "051 - TUCUMAN" "051 - TUCUMAN" "051 - TUCUMAN" "051 - TUCUMAN" ...
## $ lon : num [1:109490] -58.4 -58.4 -58.4 -58.4 -58.4 ...
## $ lat : num [1:109490] -34.6 -34.6 -34.6 -34.6 -34.6 ...
## $ FeatId1 : num [1:109490] 5507 5507 5507 5507 5507 ...
## $ MANZANA : chr [1:109490] "063B" "063B" "063B" "063B" ...
## $ SECCION : chr [1:109490] "005" "005" "005" "005" ...
## $ NIVEL : num [1:109490] 15.8 15.8 15.8 15.8 15.8 15.8 15.8 15.8 15.8 15.8 ...
## $ OBS : logi [1:109490] NA NA NA NA NA NA ...
## $ MZ_TIPO : chr [1:109490] "TIPICA" "TIPICA" "TIPICA" "TIPICA" ...
## $ CANT_LADOS : num [1:109490] 4 4 4 4 4 4 4 4 4 4 ...
## $ MZ_SUP : num [1:109490] 1903 1903 1903 1903 1903 ...
## $ CANT_PA : num [1:109490] 0 0 0 0 0 0 0 0 0 0 ...
## $ LFI : chr [1:109490] "NO" "NO" "NO" "NO" ...
## $ LIB : chr [1:109490] "NO" "NO" "NO" "NO" ...
## $ SM : chr [1:109490] "005-063B" "005-063B" "005-063B" "005-063B" ...
## $ barrio : chr [1:109490] "SAN NICOLAS" "SAN NICOLAS" "SAN NICOLAS" "SAN NICOLAS" ...
## $ comuna : num [1:109490] 1 1 1 1 1 1 1 1 1 1 ...
## $ perimetro : num [1:109490] 6548 6548 6548 6548 6548 ...
## $ area : num [1:109490] 2289008 2289008 2289008 2289008 2289008 ...
## $ geometry : chr [1:109490] "c(-58.3821223276689" "c(-58.3821223276689" "c(-58.3821223276689" "c(-58.3821223276689" ...
## - attr(*, "problems")= tibble [109,490 x 5] (S3: tbl_df/tbl/data.frame)
## ..$ row : int [1:109490] 1 2 3 4 5 6 7 8 9 10 ...
## ..$ col : chr [1:109490] NA NA NA NA ...
## ..$ expected: chr [1:109490] "24 columns" "24 columns" "24 columns" "24 columns" ...
## ..$ actual : chr [1:109490] "26 columns" "26 columns" "26 columns" "26 columns" ...
## ..$ file : chr [1:109490] "'https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro.csv'" "'https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro.csv'" "'https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro.csv'" "'https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro.csv'" ...
## - attr(*, "spec")=
## .. cols(
## .. X1 = col_double(),
## .. duracion_recorrido = col_double(),
## .. id_estacion_origen = col_double(),
## .. fecha_origen_recorrido = col_datetime(format = ""),
## .. nombre_estacion_origen = col_character(),
## .. lon = col_double(),
## .. lat = col_double(),
## .. FeatId1 = col_double(),
## .. MANZANA = col_character(),
## .. SECCION = col_character(),
## .. NIVEL = col_double(),
## .. OBS = col_logical(),
## .. MZ_TIPO = col_character(),
## .. CANT_LADOS = col_double(),
## .. MZ_SUP = col_double(),
## .. CANT_PA = col_double(),
## .. LFI = col_character(),
## .. LIB = col_character(),
## .. SM = col_character(),
## .. barrio = col_character(),
## .. comuna = col_double(),
## .. perimetro = col_double(),
## .. area = col_double(),
## .. geometry = col_character()
## .. )
Como podemos ver, nuestro dataset ya cuenta con los registros de fecha y hora en su formato correspondiente, por lo que ya podemos trabajar sobre los datos.
A fin de lograr una mayor precisión temporal, realizaremos algunas otras modificaciones al dataset.
bicis_2020 <- bicis_2020 %>%
mutate(dia = wday(fecha_origen_recorrido, label = TRUE, abbr = FALSE),
mes = month(fecha_origen_recorrido, label = TRUE, abbr = FALSE))
bicis_2020 <- bicis_2020 %>%
mutate(hora = hour(fecha_origen_recorrido))
head(bicis_2020)
## # A tibble: 6 x 27
## X1 duracion_recorri~ id_estacion_orig~ fecha_origen_recor~ nombre_estacion~
## <dbl> <dbl> <dbl> <dttm> <chr>
## 1 14674 1570 51 2020-12-11 20:40:27 051 - TUCUMAN
## 2 14675 1648 51 2020-11-21 18:05:19 051 - TUCUMAN
## 3 14676 1283 51 2020-11-13 18:32:19 051 - TUCUMAN
## 4 14677 1700 51 2020-11-10 18:14:46 051 - TUCUMAN
## 5 14678 1772 51 2020-11-02 17:35:41 051 - TUCUMAN
## 6 14679 1498 51 2020-10-06 16:14:48 051 - TUCUMAN
## # ... with 22 more variables: lon <dbl>, lat <dbl>, FeatId1 <dbl>,
## # MANZANA <chr>, SECCION <chr>, NIVEL <dbl>, OBS <lgl>, MZ_TIPO <chr>,
## # CANT_LADOS <dbl>, MZ_SUP <dbl>, CANT_PA <dbl>, LFI <chr>, LIB <chr>,
## # SM <chr>, barrio <chr>, comuna <dbl>, perimetro <dbl>, area <dbl>,
## # geometry <chr>, dia <ord>, mes <ord>, hora <int>
Como vemos, la columna “duración_recorrido” ya cuenta con la información, pero expresada en segundos. Por lo tanto, sólo nos limitaremos a traducirla en minutos.
bicis_2020 <- bicis_2020 %>%
mutate(duracion_minutos = round(as.numeric(as.duration(duracion_recorrido), "minutes"),2))
¿Cúantos minutos duran los viajes en bicicleta iniciados en el microcentro en promedio?
paste(round(mean(bicis_2020$duracion_minutos),2), " minutos es el promedio de duracion de viajes. Sin embargo, la mediana está en ", round(median(bicis_2020$duracion_minutos),2), " minutos, por lo que reconocemos que la distribución de los datos tiene una cola hacia la derecha")
## [1] "22.13 minutos es el promedio de duracion de viajes. Sin embargo, la mediana está en 16.43 minutos, por lo que reconocemos que la distribución de los datos tiene una cola hacia la derecha"
Ahora, grafiquemos para ver como se distribuyen los viajes según su duración-
ggplot(bicis_2020, aes(duracion_minutos)) +
geom_histogram(bins=50, fill="orange", alpha=.5, color="black")+
labs(x="Duración en minutos",
y="Cantidad de viajes",
title="¿Cómo es la distribución de viajes según su duración?",
subtitle = "Expresado en escala logarítica",
caption="Fuente: GCBA")+
scale_y_log10()+
scale_x_log10()+
theme_minimal()
Notamos la presencia de valores extremos, tanto superiores como inferiores. Esto puede deberse, por ejemplo, a una falla en la aplicación, o a usuarios que desbloquearon una bicicleta y la devolvieron instáneamente. Un análisis profundo sobre la duración de los viajes debería contemplar la limpieza de dichos outliers y trabajar exclusivamente con valores representativos.
#Como no se registraron viajes en el mes de Abril, agregaremos una instancia vacía
abril <- data.frame(mes=as.Date("2020-04-01")) %>%
mutate(mes = month(mes, label = TRUE, abbr = FALSE))
bicis_2020 <- full_join(bicis_2020, abril, by="mes")
ggplot(bicis_2020) +
geom_bar(aes(x = mes), fill="orange", alpha=.5, color="black") +
scale_y_continuous(limit = c(0, 20000), breaks = seq(0, 20000, 5000))+
labs(title = "Cantidad de viajes en bicicleta en el Microcentro",
subtitle = "Año 2020",
x = "Mes",
y = "Viajes",
caption = "ACLARACIÓN: En Abril no se produjeron viajes \n\ Fuente: BA Data")+
theme_minimal()+
theme(axis.text.x = element_text(face="bold", size = 7))
La caída durante los primeros meses de cuarentena resulta evidente, a tal punto que el mes de abril no registra viajes.
Curiosamente, a partir del mes de agosto (a 5 meses de haber arrancado la cuarentena), el volumen de viajes en bicicleta en el microcentro porteño supera al valor de enero, el máximo en el año previo al inicio de la pandemia. Sin embargo, ello no quiere decir que más gente use la bicicleta que en niveles pre pandemicos. Es importante mencionar que, año tras año, durante los primeros meses del calendario, la circulación en esta área geografica se reduce significativamente en comparación con su volumen habitual del resto del ciclo anual. Por ello, para poder llegar a una conclusión más profunda sobre los parámetros de uso, debiese de compararse la información con la del año 2019 (a los fines de este trabajo, omitiremos este paso por el momento).
Veamos que sucede a lo largo de las días de la semana.
ggplot(bicis_2020) +
geom_bar(aes(x = dia), fill="orange", alpha=.5, color="black") +
scale_y_continuous(limit = c(0, 20000), breaks = seq(0, 20000, 5000))+
labs(title = "Cantidad de viajes en bicicleta en el Microcentro",
subtitle = "Año 2020",
x = "Día",
y = "Viajes",
caption = "Fuente: BA Data")+
theme_minimal()
La distribución de viajes por día marca un claro contraste entre los días de semana y los fin de semanas. Es en los primeros donde se observa un mayor nivel de viajes, a un volumen similar en cada uno de los 5 días.
Repitamos el mismo análisis, pero por horas.
ggplot(bicis_2020)+
geom_bar(aes(x = hora), fill="orange", alpha=.5, color="black") +
scale_x_continuous(limit = c(-1, 24), breaks = seq(0, 23, 1))+
labs(title = "Cantidad de viajes en bicicleta en el Microcentro",
subtitle = "Año 2020",
x = "Horas",
y = "Viajes",
caption = "Fuente: BA Data")+
theme_minimal()
Durante el día, el mayor volumen de viajes en bicicleta ocurre a las 12 hs. y se mantiene en niveles similares hasta las 16 hs., cuando comienza a decaer. Como contrapartida, el mínimo volumen se registra entre 3 y 4 de la mañana.
Ahora veamos las estaciones de bicicleta que más fueron utilizadas en el microcentro durante los meses de la pandemia.
ggmap(mapamicrocentro) +
geom_sf(data=microcentro, aes(fill=MANZANA), fill="gray", alpha=.5, show.legend = FALSE, inherit.aes = FALSE)+
stat_density_2d(data = bicis_2020,
aes(x = lon, y = lat,
fill = stat(level)), alpha = 0.6, geom = "polygon", contour = TRUE) +
labs(title="Estaciones de Ecobicis en el microcentro",
subtitle="Año 2020",
caption= "Fuente: BA Data",
fill="Cantidad de usos")+
theme_void()+
scale_fill_viridis_c(option="magma", direction=-1, alpha=.6)+
theme(plot.title = element_text(hjust = 0.2),
plot.subtitle = element_text(size = 11, hjust = 0.1),
legend.title = element_text(size=9))
El gráfico muestra que durante el 2020 se utilizaron más las estaciones de Ecobicis del lado oeste de la Av. 9 de Julio que en la city porteña (algo que a simple vista se correlaciona con los usos de suelos algo direfentes entre ambos sectores del Microcentro). En ese sentido, es particularmente notable la importancia de la estación de Congreso.
Cabe descatar que no se genera un mapa de calor uniforme que cubra toda la superficie porque el agrupamiento de datos puntuales se da pares de coordenadas distantes entre sí (correspondientes a las estaciones).
Ahora veamos como fue la intensidad de usos a lo largo de los meses.
ggmap(mapamicrocentro) +
geom_bin2d(data = bicis_2020, aes(x = lon, y = lat), bins=7, alpha=.7)+
scale_fill_viridis_c()+
labs(title="Estaciones de Ecobicis en el microcentro",
subtitle="Año 2020",
caption= "ACLARACIÓN: En Abril no se produjeron viajes \n\ Fuente: BA Data",
fill="Cantidad de usos")+
facet_wrap(~mes)+
theme_void()+
theme(plot.title = element_text(hjust = 0.1),
plot.subtitle = element_text(size = 11, hjust = 0.05),
legend.title = element_text(size=9))
Al desagregar los datos por mes, notamos que la alta frecuencia de usos de bicis en la estación de Congreso se corresponden principalmente con el mes de Noviembre, momento en el cual se produjeron el mayor uso de las estaciones de Ecobicis en el Microcentro.
A su vez, resulta interesante observar como, a medida que los contagios retroceden, las restricciones disminuyen y la actividad aumenta, incrementa el uso de las estaciones de Ecobicis. Sin embargo, se muestra un claro clivaje entre las estaciones al oeste de la Av. 9 de Julio y las de la city porteña. Mientras que las primeras muestran un incremento paulatino en la actividad a través de los meses, las segundas parecen mantener un grado de actividad (bajo) a lo largo de todo año.
En este marco, la provisión de nuevos espacios verdes en el microcentro porteño puede resultar en un foco de atracción para las personas y traer mayor dinamismo al área deprimida.
Previo a realizar cualquier intervención sobre el Microcentro, debemos indagar sobre la opinión que tienen porteños sobre de la oferta actual de espacios públicos verdes en la ciudad. Por este motivo, el siguiente trabajo se propone realizar un análisis de redes a fin de identificar las principales tendencias de la opinión pública en lo respectivo a los espacios verdes del distrito, y, particularmente, los de su área central.
Consignas
Nuestro primer paso será descargar los tweets originales emitidos en la CABA que contengan las palabras “espacio verde” en cualquier parte de su estructura. Para delimitar el área, seleccionamos las coordenadas del parque Centenario y establecemos un radio de 6,5 millas, la distancia que existe en promedio al borde del distrito.
tweets_verdes <- search_tweets(q="espacios+verdes",
n=100000,
geocode = "-34.606022,-58.433788,6.5mi",
include_rts = FALSE,
retryonratelimit = TRUE)
Repetimos el proceso para la palabra “espacio público”.
tweets_publicos <- search_tweets(q = "espacio+público",
n = 100000,
geocode = "-34.606022,-58.433788,6.5mi",
include_rts = FALSE,
retryonratelimit = TRUE)
Si bien hicimos la consulta por 100000 tweets de la última semana, notamos que para ambos búsquedas sólo obtuvimos un 1% de la cantidad pedida. Esto nos demuestra que son temas poco mencionados en twitter al momento del análisis.
Unimos ambos datasets.
tweets <- union_all(tweets_verdes, tweets_publicos)
La cantidad de tweets obtenida para cada una de las búsquedas fue:
paste("Espacios verdes: ", length(tweets_verdes))
## [1] "Espacios verdes: 90"
paste("Espacio público: ", length(tweets_publicos))
## [1] "Espacio público: 90"
Ahora veremos la popularidad de los twiteros en cuestión.
ggplot(tweets) +
geom_histogram(aes(x = followers_count), fill="orange", alpha=.5, color="black")+
scale_y_continuous(limit = c(0, 90), breaks = seq(0, 90, 10))+
labs(title = "Cantidad de cuentas de twitter",
subtitle = "Por seguidores",
y="Cuentas",
x="Seguidores",
caption = "Fuente: Twitter")+
theme_minimal()
A simple vista, la gran mayoría de los twitteros poseen solo un puñado de seguidores. Pero tambien reconocemos la presencia de unos pocos usuarios que acumula una gran cantidada de seguidores.
Veamos con mayor profundidad.
Obtenemos un top 10 de los usuarios más populares.
tweets %>%
select(screen_name, followers_count) %>%
distinct() %>%
arrange(desc(followers_count)) %>%
top_n(10)
## # A tibble: 10 x 2
## screen_name followers_count
## <chr> <int>
## 1 C5N 2842601
## 2 gcba 1891389
## 3 tiempoarg 552878
## 4 Lubertino 120021
## 5 igonzalezprieto 95112
## 6 pietragallahora 71338
## 7 Volquetere 47758
## 8 dievalen 42801
## 9 rindart 39511
## 10 nciudad 34249
De nuestra muestra, vemos que el usuario más popular es el GCBA, seguido, en su mayoría, por medios periodísticos y periodistas.
En esta línea, veamos el tweet más popular y su contenido.
tweets %>%
select(screen_name, text, retweet_count) %>%
distinct() %>%
arrange(desc(retweet_count)) %>%
head(10)
## # A tibble: 10 x 3
## screen_name text retweet_count
## <chr> <chr> <int>
## 1 tiempoarg "CABA: Mientras flexibilizan actividades en esp~ 38
## 2 Volquetere "Ya me aprobaron Okupas 2 en Netflix, es la his~ 28
## 3 dievalen "Está quedando buenísima la plaza Lodelpa de Ci~ 23
## 4 igonzalezprie~ "Estación #Saavedra 4 hombres jóvenes pintaron ~ 16
## 5 DiarioConurba~ "<U+26A0><U+FE0F>Estación #Saavedra: Cuatro hombres pintaron a~ 9
## 6 paisajeante "Este miércoles 28/07 a las 17:30 hs. \U0001f44~ 7
## 7 ahcolombo "En la Plaza de la Misericordia de Flores, dond~ 6
## 8 lucampora "“Las tierras públicas son de todxs. Son reserv~ 6
## 9 dangigena1 "a partir del incidente de \"Showmatch\" en el ~ 6
## 10 Camilinsanchez "\U0001f30a• Somos muchos y muchas las que deci~ 5
Al observar nuestros datos, podemos ver que los tweets seleccionados poseen un volumen relativamente bajo de retweets. Curiosamente, los tweets más populares de nuestras muestra no fueron escritos por ninguna de las 5 cuentas más populares anteriormente mencionadas.
Luego, en cuanto al contenido, los tweets parecen dividirse en dos grupos: aquellos que expresan una posición crítica frente a la gestión del GCBA en cuanto a los espacios verdes de la ciudad, y aquellos que refieren a otras cuestiones que poco tienen que ver con la oferta de estos lugares.
Ahora veremos a qué hora se twittea con mayor intensidad sobre los temas de interés.
tweets %>%
count(hora = hour(with_tz(created_at, "America/Argentina/Buenos_Aires"))) %>%
ggplot() +
geom_col(aes(x = hora, y = n), fill="orange", alpha=.5, color="black")+
scale_y_continuous(limit = c(0, 12), breaks = seq(0, 12, 2))+
scale_x_continuous(limit = c(-1, 24), breaks = seq(0, 23, 1))+
labs(title = "Cantidad de tweets",
subtitle = "Por horas del día",
y="Tweets",
x="Horas",
caption = "Fuente: Twitter")+
theme_minimal()+
geom_smooth(aes(x = hora, y = n), color="brown4", linetype="dashed", method = "loess", se=FALSE)
Podemos ver que la gente twittea más a medida que avanza el día, y llega a un pico de actividad en la mitad de la tarde (entre las 16 y 17 hs). A partir de allí comienza a caer la actividad, con otro pico registrado a las 22hs.
Ahora bien, veamos desde donde twittean los usuarios que hablan sobre nuestra temática de interés. Para eso:
1º. Extraemos las coordenadas de nuestros tweets
tweets_geo <- lat_lng(tweets)
Filtramos para solo quedarnos con los tweets que tienen coordenadas precisas.
tweets_geo <- tweets_geo %>%
filter(!is.na(lat), !is.na(lng))
Graficamos
leaflet(tweets_geo) %>%
addTiles() %>%
addMarkers(popup = ~paste("user:", screen_name,
"followers", followers_count,
"tweet:", text),
lat = ~jitter(lat, 50),
lng = ~jitter(lng, 50))
Como conclusión, llama la atención la poca relevancia que parece tener la temática de los espacios verdes públicos en Twitter, a pesar de ser un tema de actualidad y suma importancia. Las consultas realizadas no arrojaron una cantidad de resultados suficientes como para entender la opinión popular. Es probable que al momento del análisis la agenda twittera haya estado ocupada con otros temas de interés.
Luego de haber identificado las estaciones de Ecobicis más frecuentadas del microcentro y el comportamiento de los usuarios a lo largo del año 2020, en este trabajo nos preguntamos:
¿Cúales fueron los viajes en bicicleta más comunes dentro del microcentro?
¿Existe alguna correlación espacial entre las estaciones origen-destino?
¿Cuán frecuentes son los viajes circulares en el área?
Consignas
Para realizar este ejercicio, utilizamos un dataset previamente filtrado de recorridos de bicicletas públicas del GCBA. A diferencia del dataset empleado anterioremente durante la cursada, en esta oportunidad, nos quedamos sólo con los recorridos que iniciaron y finalizaron dentro del microcentro porteño. Omitimos este paso debido al gran peso del archivo base.
La decisión de limitarnos espacialmente no sólo tiene que ver, entender el comportamiento exclusivamente dentro del área, sino también con reducir el tiempo de cómputo. Sin embargo, reconocemos que un análisis más completo debería considerar la influencia del resto de la ciudad.
Ahora sí, procedemos a cargar el nuevo dataset filtrado:
viajesbicis_microcentro <- read.csv("https://raw.githubusercontent.com/MEU-CDPC2/TPS/main/Datasets/bicis_microcentro_origen_destino.csv", stringsAsFactors = TRUE, encoding = "UTF-8")
head(viajesbicis_microcentro)
## X duracion_recorrido id_estacion_origen fecha_origen_recorrido
## 1 1 442 83 2020-11-24 20:02:36
## 2 2 2083 83 2020-03-13 10:48:44
## 3 3 2 8 2020-12-12 22:33:00
## 4 4 2805 8 2020-11-19 19:20:02
## 5 5 683 8 2020-11-03 17:46:43
## 6 6 2873 8 2020-10-12 13:08:46
## nombre_estacion_origen fecha_destino_recorrido id_estacion_destino
## 1 083 - Paraná 2020-11-24 20:09:58 8
## 2 083 - Paraná 2020-03-13 11:23:27 8
## 3 008 - Congreso 2020-12-12 22:33:02 8
## 4 008 - Congreso 2020-11-19 20:06:47 8
## 5 008 - Congreso 2020-11-03 17:58:06 8
## 6 008 - Congreso 2020-10-12 13:56:39 8
## nombre_estacion_destino id_usuario direccion_estacion_origen
## 1 008 - Congreso 7705 1590 Lavalle
## 2 008 - Congreso 331437 1590 Lavalle
## 3 008 - Congreso 569327 Cevallos, Virrey& Yrigoyen, Hipolito Av.
## 4 008 - Congreso 88589 Cevallos, Virrey& Yrigoyen, Hipolito Av.
## 5 008 - Congreso 231982 Cevallos, Virrey& Yrigoyen, Hipolito Av.
## 6 008 - Congreso 706412 Cevallos, Virrey& Yrigoyen, Hipolito Av.
## long_estacion_origen lat_estacion_origen
## 1 -58.38937 -34.60327
## 2 -58.38937 -34.60327
## 3 -58.38933 -34.60942
## 4 -58.38933 -34.60942
## 5 -58.38933 -34.60942
## 6 -58.38933 -34.60942
## direccion_estacion_destino long_estacion_destino
## 1 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## 2 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## 3 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## 4 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## 5 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## 6 Cevallos, Virrey& Yrigoyen, Hipolito Av. -58.38933
## lat_estacion_destino periodo
## 1 -34.60942 2020
## 2 -34.60942 2020
## 3 -34.60942 2020
## 4 -34.60942 2020
## 5 -34.60942 2020
## 6 -34.60942 2020
Notamos que sólo existen 99 recorridos inicados y finalizados dentro del microcentro.
Indaguemos con mayor profundidad las característas que presentan los viajes dentro de esta área.
¿Cúantos minutos duran los viajes en bicicleta iniciados y finalizados dentro del microcentro en promedio?
viajesbicis_microcentro <- viajesbicis_microcentro %>%
mutate(duracion_minutos = round(as.numeric(as.duration(duracion_recorrido), "minutes"),2))
paste(round(mean(viajesbicis_microcentro$duracion_minutos),2), "minutos es el promedio de duracion de los viajes realizados en el área central de la CABA. Sin embargo, la mediana está en", round(median(viajesbicis_microcentro$duracion_minutos),2), "minutos, por lo que, al igual que en el análisis correspondiente al TP3, reconocemos un sesgo positivo frente a valores extremos.")
## [1] "15.4 minutos es el promedio de duracion de los viajes realizados en el área central de la CABA. Sin embargo, la mediana está en 11.53 minutos, por lo que, al igual que en el análisis correspondiente al TP3, reconocemos un sesgo positivo frente a valores extremos."
Al limitar el área de origen y destino notamos una reducción del tiempo promedio de los viajes de 43.76%.
¿Cómo es la distribución de viajes entre estaciones de Ecobicis?
1º. Creamos un dataset que agrupe los viajes por estación de origen y estación de destino.
viajes <- viajesbicis_microcentro %>%
group_by(id_estacion_origen, nombre_estacion_origen, id_estacion_destino, nombre_estacion_destino, long_estacion_origen, lat_estacion_origen, long_estacion_destino, lat_estacion_destino) %>%
summarise(cant_viajes = n())
2º. Graficamos la distribución de viajes entre estaciones.
ggplot() +
geom_tile(data = viajes, aes(x = as.factor(id_estacion_origen), y = as.factor(id_estacion_destino), fill = cant_viajes)) +
labs(title="Matriz Origen-Destino",
subtitle = "Estaciones de Ecobicis del microcentro porteño",
y="Estación de origen",
x="Estación de destino",
fill="Viajes",
caption = "Fuente: BA Data")+
scale_fill_viridis_c(breaks=c(0,3,6,9,12),
limits=c(0,12))+
theme_minimal()
A simple vista, observamos una distribución pareja de viajes entre estaciones del microcentro. No obstante, podemos evidenciar que existe una considerable presencia de viajes circulares, principalmente, para las estaciones 8 (Congreso), 144 (Pueyrredon) y 183 (Virrey Cevallos).
viajes %>%
arrange(desc(cant_viajes)) %>%
head(3)
## # A tibble: 3 x 9
## # Groups: id_estacion_origen, nombre_estacion_origen, id_estacion_destino,
## # nombre_estacion_destino, long_estacion_origen, lat_estacion_origen,
## # long_estacion_destino [3]
## id_estacion_origen nombre_estacion_ori~ id_estacion_dest~ nombre_estacion_des~
## <int> <fct> <int> <fct>
## 1 8 008 - Congreso 8 008 - Congreso
## 2 144 144 - PUEYRREDÓN 144 144 - PUEYRREDÓN
## 3 183 183 - VIRREY CEVALL~ 183 183 - VIRREY CEVALL~
## # ... with 5 more variables: long_estacion_origen <dbl>,
## # lat_estacion_origen <dbl>, long_estacion_destino <dbl>,
## # lat_estacion_destino <dbl>, cant_viajes <int>
Veamoslo de otra manera:
viajes_top10 <- viajes %>%
mutate(viajes_circulares = if_else(id_estacion_origen==id_estacion_destino, "si", "no"),
ruta = paste("Desde", nombre_estacion_origen, "\n Hasta", nombre_estacion_destino)) %>%
arrange(desc(cant_viajes)) %>%
head(10)
ggplot(viajes_top10, aes(y=reorder(ruta, -cant_viajes), x=cant_viajes, fill=viajes_top10$viajes_circulares)) +
geom_bar(stat="identity", alpha=.5, color="black")+
scale_x_continuous(breaks = seq(0,12,3),
limits = c(0,12))+
labs(title = "Top 10 viajes más realizados en bici",
subtitle = "Entre estaciones de Ecobicis del Microcentro",
x = "Cantidad de viajes",
y = "Recorrido",
fill = "Viaje \n circular",
caption = "Fuente: BA Data")+
theme_minimal()
Como podemos ver, 6 de los 10 viajes más realizados en el Microcentro son circulares. De dichos 6, 4 integran el top 5, entre las posiciones 1 y 4. Por este motivo, podemos concluir que la mayoría de los viajes que se realizan al interior del Microcento son circulares.
Una cuestión a tener en cuenta es que los viajes desde la estación Paraná a la estación Congreso (y viceversa) parecen realizarce con una frecuencia considerable. Tal es así que, si sumamos ambas, el trayecto pasaría a ser considerado como uno de los más frecuentes por los usuarios al interior del Microcentro.
Ahora, veamos la distribución de los viajes circulares en el territorio.
1º. Creemos un dataset que contenga solo viajes circulares.
circulares <- viajes[which(viajes$id_estacion_origen == viajes$id_estacion_destino), ]
2º. Transformemos nuestro dataset en uno espacial.
circulares<- st_as_sf(circulares, coords = c("long_estacion_origen", "lat_estacion_origen"), crs = 4326)
3º. Grafiquemos.
ggplot()+
geom_sf(data = microcentro, fill="grey96")+
geom_sf(data = espacioverde, fill="springgreen2")+
geom_sf(data= circulares, aes(size=cant_viajes),color="orange", alpha=0.8)+
labs(title = "¿Donde se ubican los viajes circulares más frecuentes?",
color="Cantidad de viajes",
subtitle = "Estaciones de bicis del microcentro porteño",
size="Viajes",
caption = "Fuente: BA Data")+
scale_size_continuous(range = c(4, 10), breaks= c(2,4,6,8, 10))+
theme_void()
Como vimos anteriormente, los 10 recorridos más realizados son:
viajes_top10 %>%
select(ruta, cant_viajes, viajes_circulares)
## # A tibble: 10 x 10
## # Groups: id_estacion_origen, nombre_estacion_origen, id_estacion_destino,
## # nombre_estacion_destino, long_estacion_origen, lat_estacion_origen,
## # long_estacion_destino [10]
## id_estacion_origen nombre_estacion_ori~ id_estacion_dest~ nombre_estacion_de~
## <int> <fct> <int> <fct>
## 1 8 008 - Congreso 8 008 - Congreso
## 2 144 144 - PUEYRREDÓN 144 144 - PUEYRREDÓN
## 3 183 183 - VIRREY CEVALL~ 183 183 - VIRREY CEVAL~
## 4 171 171 - Pasteur 171 171 - Pasteur
## 5 8 008 - Congreso 183 183 - VIRREY CEVAL~
## 6 83 083 - Paraná 83 083 - Paraná
## 7 8 008 - Congreso 83 083 - Paraná
## 8 83 083 - Paraná 8 008 - Congreso
## 9 83 083 - Paraná 144 144 - PUEYRREDÓN
## 10 132 132 - CORRIENTES 132 132 - CORRIENTES
## # ... with 6 more variables: long_estacion_origen <dbl>,
## # lat_estacion_origen <dbl>, long_estacion_destino <dbl>, ruta <chr>,
## # cant_viajes <int>, viajes_circulares <chr>
A continuación, procederemos a mapaear los ruteos.
1º. Creamos una función que calcule las rutas entre estaciones de Ecobicis.
ruteo_bikes <- function(nombre_estacion_origen, long_estacion_origen, lat_estacion_origen,
nombre_estacion_destino, long_estacion_destino, lat_estacion_destino) {
ruta <- osrmRoute(src = c(nombre_estacion_origen, long_estacion_origen, lat_estacion_origen),
dst = c(nombre_estacion_destino, long_estacion_destino, lat_estacion_destino),
returnclass = "sf",
overview = "full",
osrm.profile = "bike")
cbind(ORIGEN = nombre_estacion_origen, DESTINO = nombre_estacion_destino, ruta)}
2º. Generamos una lista que contenga los casos a analizar.
ruteo_top_10 <- list(viajes_top10$nombre_estacion_origen, viajes_top10$long_estacion_origen, viajes_top10$lat_estacion_origen, viajes_top10$nombre_estacion_destino, viajes_top10$long_estacion_destino, viajes_top10$lat_estacion_destino)
3º. Aplicamos nuestra función.
ruteo_top_10 <- pmap(ruteo_top_10, ruteo_bikes) %>%
reduce(rbind)
4º. Graficamos.
ruteo_top_10 <- ruteo_top_10 %>%
st_jitter(amount=.0005) #separamos levemente los recorridos para evitar superposición y visualizarlos a todos
ggmap(mapamicrocentro)+
geom_sf(data=ruteo_top_10, aes(color=duration), size=1.5, inherit.aes = FALSE)+
geom_sf(data= circulares, aes(size=cant_viajes),color="orange", alpha=0.8, inherit.aes = FALSE)+
labs(title="Recorridos más realizados en Bicicleta en el Microcento",
fill="",
size=" Viajes \n circulares\n por estación\n de Ecobici",
color="Duración \n (Minutos)",
caption="Fuente: BA Data.\n Aclaración: Ante la imposibilidad de graficar el recorrido de los viajes circulares,\n la variable duración solo aplica a los recorridos lineales.")+
scale_color_viridis_c(breaks=seq(0,8,2),
limits=c(0,8))+
scale_size_continuous(range = c(4, 10), breaks= c(2,4,6,8, 10))+
theme_void()
Evidenciamos que, además de los viajes ciruculares, imposibles de graficar por falta de ruteo, los recorrridos más frecuentes se cocentran por las ciclovías de las calles Tucumán y Motevideo.
Además, notamos que las estaciones con mayor frecuencia de viajes circulares se ubican geográficamente en la misma traza. El único ruteo que se superpone en nuestro top 10 de viajes más frecuentes, es el correspondiente al tramo de las estaciones Congreso-Paraná, que registra viajes en ambos sentidos.
paleta <- c(low="gold", high= "red")
leaflet(ruteo_top_10) %>%
addTiles() %>%
addPolylines(color = ~colorNumeric(paleta, ruteo_top_10$distance)(distance),
weight = 6,
label = paste("Ruta: Desde", ruteo_top_10$ORIGEN,
"hasta", ruteo_top_10$DESTINO,"|",
"Distancia:", round((ruteo_top_10$distance),2),"KM", "|",
"Duración:", round((ruteo_top_10$duration),0),"min."))